#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "cmd_curl.h"
#include "cJSON.h"

#define MAX_HTTP_RECV_BUFFER 512
#define CURL_URL "http://httpbin.org"
static const char * TAG = "CURL";


/*
static void register_***();   命令注册声明
在命令组注册函数添加命令注册
命令参数结构体构造
命令处理函数
命令注册绑定函数

 */

static struct {
    struct arg_str *method;     //请求方式
    struct arg_str *header;     //头部信息
    struct arg_str *data;       //请求数据
	struct arg_str *url;		//url
	struct arg_end *end;
} curl_arg;




//私有函数
esp_err_t curl_http_event_handler(esp_http_client_event_t *evt)
{
    switch(evt->event_id) {
        case HTTP_EVENT_ERROR:
            ESP_LOGD(TAG, "HTTP_EVENT_ERROR 错误");      //错误
            break;
        case HTTP_EVENT_ON_CONNECTED:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED 连接");   //连接
            break;
        case HTTP_EVENT_HEADER_SENT:
            ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT 发送头");    //头发送
            break;
        case HTTP_EVENT_ON_HEADER:                      //打开头
            ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER 打开头, key=%s, value=%s", evt->header_key, evt->header_value);
            printf("HEADER 头部信息\t %s：%s\n", evt->header_key, evt->header_value);
            break;
        case HTTP_EVENT_ON_DATA:                        //打开数据
            ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA 打开数据, len=%d", evt->data_len);
            if (!esp_http_client_is_chunked_response(evt->client)) {
                // Write out data
                printf("%.*s", evt->data_len, (char*)evt->data);
            }else{
                printf("%.*s", evt->data_len, (char*)evt->data);
            }

            break;
        case HTTP_EVENT_ON_FINISH:      //结束
            ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
            break;
        case HTTP_EVENT_DISCONNECTED:   //断开连接
            ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
            break;
    }
    return ESP_OK;
}



void curl_task(void *pvParameter){
    //初始化变量
    const char * method_="get";
    
    esp_http_client_config_t config = {
        .url = CURL_URL,                              //url地址
        .event_handler = curl_http_event_handler,           //事件处理函数
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);        //配置



    if(curl_arg.url->count){ 
        esp_http_client_set_url(client,curl_arg.url->sval[0]);
        printf("设置url %s\n",curl_arg.url->sval[0]);
    }
    if(curl_arg.method->count){
        method_=curl_arg.method->sval[0];
        if(strcmp(method_,"post") == 0){
            esp_http_client_set_method(client, HTTP_METHOD_POST);//设置请求模式
            printf("设置请求模式 %s \n",method_);
        }else{
            printf("模式错误！\n");
        }

    }
    
    for(int i =0;i<curl_arg.header->count;i++){
        char key[24],val[64];
        sscanf(curl_arg.header->sval[i],"%s %s",key,val);
        printf("header%d %s:%s\n",i,key,val);
        esp_http_client_set_header(client,key,val);
    }

    if(curl_arg.data->count){
        esp_http_client_set_post_field(client, curl_arg.data->sval[0],strlen(curl_arg.data->sval[0]));
        printf("设置数据 %s\n",curl_arg.data->sval[0]);
    }
    
    
    //printf("向发送curl请求\n");
    //执行post请求
    esp_err_t err = esp_http_client_perform(client);
    if(esp_http_client_is_chunked_response(client)) printf("分块编码\n");
    //检测请求结果
    if (err == ESP_OK) {
        ESP_LOGI(TAG, "HTTP %s 状态 = %d, content 长度 = %d",
                method_,
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {
        ESP_LOGE(TAG, "HTTP %s 请求失败: %s",method_, esp_err_to_name(err));
    }
    esp_http_client_cleanup(client);
    vTaskDelete(NULL);
}


//命令处理函数
static int cmd_curl(int argc, char** argv){
    
    int nerrors = arg_parse(argc, argv, (void**) &curl_arg);
    if (nerrors != 0) {
        arg_print_errors(stderr, curl_arg.end, argv[0]);
        return 1;
    }
    printf("创建任务curl\n");
	xTaskCreate(&curl_task, "curl", 8192, NULL, 5, NULL);
    return 0;
    
    
}



//命令注册函数
void register_curl(void){
	//参数表格式化
    curl_arg.header = arg_str0("h",NULL, "<str>", "头部键值对");
    curl_arg.method = arg_str0("m",NULL, "<str>", "请求方式，默认get.");
    curl_arg.data = arg_str0("d",NULL, "<str>", "请求数据.");
    curl_arg.url = arg_str0(NULL,NULL, "<str>", "url地址.");
    curl_arg.end = arg_end(1);
	//命令注册
	const esp_console_cmd_t cmd = {
        .command = "curl",
        .help = "简易版curl命令行",
        .hint = "-h -m -d url",
        .func = &cmd_curl,
        .argtable = &curl_arg
    };
    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
}